<template>
  <div class="cursor-container">
    <!-- 主光标 -->
    <div 
      ref="cursor" 
      class="cursor"
      :class="{ 'cursor-hover': isHovering }"
    ></div>
    
    <!-- 光标跟随圆圈 -->
    <div 
      ref="cursorFollower" 
      class="cursor-follower"
      :class="{ 'cursor-follower-hover': isHovering }"
    ></div>
    
    <!-- 光标轨迹 -->
    <div 
      v-for="(trail, index) in trails" 
      :key="index"
      class="cursor-trail"
      :style="{
        left: trail.x + 'px',
        top: trail.y + 'px',
        opacity: trail.opacity,
        transform: `scale(${trail.scale})`
      }"
    ></div>
  </div>
</template>

<script>
import { COLORS, PERFORMANCE } from '@/config/constants.js'

export default {
  name: 'MouseCursor',
  data() {
    return {
      mouseX: 0,
      mouseY: 0,
      cursorX: 0,
      cursorY: 0,
      followerX: 0,
      followerY: 0,
      isHovering: false,
      trails: [],
      maxTrails: 8,
      animationId: null,
      idleCallbackId: null,
      trailsNeedUpdate: false
    }
  },
  mounted() {
    this.initCursor()
    this.animate()
    document.addEventListener('mousemove', this.handleMouseMove)
    document.addEventListener('mouseenter', this.handleMouseEnter)
    document.addEventListener('mouseleave', this.handleMouseLeave)
    
    // 检测悬停元素
    this.addHoverListeners()
  },
  beforeUnmount() {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId)
    }
    if (this.idleCallbackId) {
      cancelIdleCallback(this.idleCallbackId)
    }
    document.removeEventListener('mousemove', this.handleMouseMove)
    document.removeEventListener('mouseenter', this.handleMouseEnter)
    document.removeEventListener('mouseleave', this.handleMouseLeave)
    document.removeEventListener('mouseover', this.handleDelegatedMouseOver)
    document.removeEventListener('mouseout', this.handleDelegatedMouseOut)
  },
  methods: {
    initCursor() {
      // 隐藏默认光标
      document.body.style.cursor = 'none'
    },
    handleMouseMove(e) {
      this.mouseX = e.clientX
      this.mouseY = e.clientY
      
      // 添加轨迹点
      this.addTrail(e.clientX, e.clientY)
    },
    handleMouseEnter() {
      this.$refs.cursor.style.opacity = '1'
      this.$refs.cursorFollower.style.opacity = '1'
    },
    handleMouseLeave() {
      this.$refs.cursor.style.opacity = '0'
      this.$refs.cursorFollower.style.opacity = '0'
    },
    addHoverListeners() {
      // 使用事件委托为可交互元素添加悬停效果
      document.addEventListener('mouseover', this.handleDelegatedMouseOver)
      document.addEventListener('mouseout', this.handleDelegatedMouseOut)
    },
    handleDelegatedMouseOver(event) {
      // 检查目标元素是否为可交互元素
      if (this.isInteractiveElement(event.target)) {
        this.isHovering = true
      }
    },
    handleDelegatedMouseOut(event) {
      // 检查目标元素是否为可交互元素
      if (this.isInteractiveElement(event.target)) {
        this.isHovering = false
      }
    },
    isInteractiveElement(element) {
      // 检查元素是否为可交互元素
      const interactiveSelectors = ['a', 'button', '.qq-group', '[role="button"]']
      
      return interactiveSelectors.some(selector => {
        if (selector.startsWith('.')) {
          // 类选择器
          return element.classList && element.classList.contains(selector.slice(1))
        } else if (selector.startsWith('[')) {
          // 属性选择器
          const attrMatch = selector.match(/\[(.+?)="(.+?)"\]/)
          if (attrMatch) {
            return element.getAttribute(attrMatch[1]) === attrMatch[2]
          }
          return false
        } else {
          // 标签选择器
          return element.tagName && element.tagName.toLowerCase() === selector.toLowerCase()
        }
      })
    },
    addTrail(x, y) {
      this.trails.push({
        x: x - 4,
        y: y - 4,
        opacity: 0.8,
        scale: 1,
        timestamp: Date.now()
      })
      
      // 限制轨迹数量
      if (this.trails.length > this.maxTrails) {
        this.trails.shift()
      }
      
      // 标记轨迹需要更新
      this.trailsNeedUpdate = true
      this.scheduleTrailUpdate()
    },
    updateTrails() {
      const now = Date.now()
      this.trails = this.trails.filter(trail => {
        const age = now - trail.timestamp
        const maxAge = PERFORMANCE.TRAIL_MAX_AGE
        
        if (age > maxAge) {
          return false
        }
        
        // 更新透明度和缩放
        const progress = age / maxAge
        trail.opacity = 0.8 * (1 - progress)
        trail.scale = 1 - progress * 0.5
        
        return true
      })
      this.trailsNeedUpdate = false
    },
    scheduleTrailUpdate() {
      // 如果已经有待处理的更新，则跳过
      if (this.idleCallbackId || !this.trailsNeedUpdate) {
        return
      }
      
      // 使用 requestIdleCallback 在浏览器空闲时更新轨迹
      if (window.requestIdleCallback) {
        this.idleCallbackId = requestIdleCallback((deadline) => {
          // 如果有足够的空闲时间或者轨迹数量过多，立即更新
          if (deadline.timeRemaining() > 5 || this.trails.length > this.maxTrails * 1.5) {
            this.updateTrails()
          }
          this.idleCallbackId = null
        }, { timeout: PERFORMANCE.IDLE_CALLBACK_TIMEOUT })
      } else {
        // 降级方案：使用 setTimeout
        this.idleCallbackId = setTimeout(() => {
          this.updateTrails()
          this.idleCallbackId = null
        }, 16) // 约60fps
      }
    },
    animate() {
      // 平滑跟随动画
      const ease = 0.15
      const followerEase = 0.08
      
      // 主光标跟随
      this.cursorX += (this.mouseX - this.cursorX) * ease
      this.cursorY += (this.mouseY - this.cursorY) * ease
      
      // 跟随圆圈
      this.followerX += (this.mouseX - this.followerX) * followerEase
      this.followerY += (this.mouseY - this.followerY) * followerEase
      
      // 更新DOM
      if (this.$refs.cursor) {
        this.$refs.cursor.style.transform = `translate3d(${this.cursorX - 8}px, ${this.cursorY - 8}px, 0)`
      }
      
      if (this.$refs.cursorFollower) {
        this.$refs.cursorFollower.style.transform = `translate3d(${this.followerX - 20}px, ${this.followerY - 20}px, 0)`
      }
      
      // 如果轨迹需要更新且没有待处理的空闲回调，则立即更新
      if (this.trailsNeedUpdate && !this.idleCallbackId) {
        this.updateTrails()
      }
      
      this.animationId = requestAnimationFrame(this.animate)
    }
  }
}
</script>

<style scoped>
.cursor-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}

.cursor {
  position: fixed;
  width: 16px;
  height: 16px;
  background: var(--primary-gradient);
  border-radius: 50%;
  pointer-events: none;
  z-index: 9999;
  transition: transform 0.1s ease-out, opacity 0.3s ease;
  box-shadow: 0 0 20px rgba(102, 126, 234, 0.6);
}

.cursor-hover {
  transform: scale(1.5) !important;
  background: linear-gradient(135deg, #ff7eb3 0%, #ff758c 100%);
  box-shadow: 0 0 30px rgba(255, 126, 179, 0.8);
}

.cursor-follower {
  position: fixed;
  width: 40px;
  height: 40px;
  border: 2px solid rgba(102, 126, 234, 0.3);
  border-radius: 50%;
  pointer-events: none;
  z-index: 9998;
  transition: transform 0.2s ease-out, opacity 0.3s ease, border-color 0.3s ease;
}

.cursor-follower-hover {
  transform: scale(1.2) !important;
  border-color: rgba(255, 126, 179, 0.6);
  border-width: 3px;
}

.cursor-trail {
  position: fixed;
  width: 8px;
  height: 8px;
  background: var(--primary-gradient);
  border-radius: 50%;
  pointer-events: none;
  z-index: 9997;
  transition: opacity 0.1s ease-out;
}

/* 隐藏默认光标 */
:global(body) {
  cursor: none !important;
}

:global(a, button, .qq-group, [role="button"]) {
  cursor: none !important;
}

/* 移动端隐藏自定义光标 */
@media (max-width: 768px) {
  .cursor-container {
    display: none;
  }
  
  :global(body) {
    cursor: auto !important;
  }
  
  :global(a, button, .qq-group, [role="button"]) {
    cursor: pointer !important;
  }
}
</style>